package health

import (
	"encoding/json"
	"errors"
	"gitee.com/g-qs/gin-vue-admin/server/global"
	"gitee.com/g-qs/gin-vue-admin/server/model/health"
	healthReq "gitee.com/g-qs/gin-vue-admin/server/model/health/request"
	healthRes "gitee.com/g-qs/gin-vue-admin/server/model/health/response"
	public2 "gitee.com/g-qs/gin-vue-admin/server/model/public"
	"gitee.com/g-qs/gin-vue-admin/server/model/topic"
	"gitee.com/g-qs/gin-vue-admin/server/model/user"
	"gitee.com/g-qs/gin-vue-admin/server/service/public"
	"gorm.io/gorm"
	"strconv"
)

type CircleService struct {
}

var messageService = new(public.MessageService)

// CreateCircle 创建健康圈
// Author: [g-qs](https://github.com/g-qs)
func (circleService *CircleService) CreateCircle(circle *health.Circle) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 创建健康圈数据
		if err := tx.Create(&circle).Error; err != nil {
			return err
		}
		// 增加参与话题数
		if err = global.GVA_DB.Model(&topic.Topic{}).Where("id = ?", circle.Tid).UpdateColumn("number", gorm.Expr("number + ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
}

// CreateCircleComment 创建健康圈评论
// Author: [g-qs](https://github.com/g-qs)
func (circleService *CircleService) CreateCircleComment(comment *health.CircleComment) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 创建健康圈评论
		if err := global.GVA_DB.Create(comment).Error; err != nil {
			return err
		}
		// 增加评论数
		if err = global.GVA_DB.Model(&health.Circle{}).Where("c_id = ?", comment.Cid).UpdateColumn("comment_num", gorm.Expr("comment_num + ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
}

// GetCircleInfoList 分页获取健康圈列表
func (circleService *CircleService) GetCircleInfoList(info healthReq.ReqCircle) (list []healthRes.NewCircleResponse, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	//var result []healthRes.CircleResponse
	var result []healthRes.NewCircleResponse
	var circles []health.Circle
	//err = global.GVA_DB.Model(&health.Circle{}).Debug().
	//	Select("fd_circle.c_id,fd_user.name,fd_user.avatar,fd_topic.name as topic,fd_circle.text,fd_circle.img,fd_circle.views,fd_circle.praise_num,fd_circle.comment_num").
	//	Joins("left join fd_user on fd_circle.u_id = fd_user.id").Joins("left join fd_topic on fd_topic.id = fd_circle.t_id").
	//	Limit(limit).Offset(offset).Where("fd_circle.status = ?", 2).Find(&circle).Scan(&circle).Error
	//if err != nil {
	//	return
	//}
	// 创建db
	db := global.GVA_DB.Model(&circles)
	if info.Tid != 0 {
		db = db.
			Where("t_id = ? AND status = ?", info.Tid, 2)
	} else {
		db = db.
			Where("status = ?", 2)
	}
	if err = db.Order("create_at desc").Limit(limit).Offset(offset).Preload("User").Preload("Topic").Find(&circles).Error; err != nil {
		return result, err
	}
	for _, circle := range circles {
		//circleResponse := healthRes.CircleResponse{
		//	Cid:        circle.Cid,
		//	Name:       circle.User.Name,
		//	Avatar:     circle.User.Avatar,
		//	TopicName:  circle.Topic.Name,
		//	Text:       circle.Text,
		//	Img:        circle.Img,
		//	CreatedAt:  circle.CreatedAt,
		//	Views:      circle.PraiseNum, // 位置调换
		//	PraiseNum:  circle.Views,     // 位置调换
		//	CommentNum: circle.CommentNum,
		//	IsPraise:   circle.IsPraise,
		//}
		var praiseNum string
		var commentNum string
		if circle.PraiseNum > 0 {
			praiseNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
		} else {
			praiseNum = "1w+"
		}
		if circle.CommentNum > 0 {
			commentNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
		} else {
			commentNum = "1w+"
		}
		circleResponse := healthRes.NewCircleResponse{
			Cid:        circle.Cid,
			Name:       circle.User.Name,
			Avatar:     circle.User.Avatar,
			TopicName:  circle.Topic.Name,
			Text:       circle.Text,
			Img:        circle.Img,
			CreatedAt:  circle.CreatedAt,
			Views:      strconv.Itoa(int(circle.Views)) + "w+",
			PraiseNum:  praiseNum,
			CommentNum: commentNum,
			IsPraise:   circle.IsPraise,
		}
		result = append(result, circleResponse)
	}
	return result, err
}

// GetHealthCircleList 分页获取健康圈列表【管理端】
func (circleService *CircleService) GetHealthCircleList(info healthReq.HealthCircleSearch) (list []healthRes.NewCircleResponse, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var result []healthRes.NewCircleResponse
	var circles []health.Circle
	// 创建db
	db := global.GVA_DB.Model(&health.Circle{})
	if info.Tid != 0 {
		db = db.Where("t_id = ? AND status = 2", info.Tid)
	} else {
		db = db.Where("status = 2")
	}
	if info.Text != "" {
		db = db.Where("text LIKE ?", "%"+info.Text+"%")
	}
	var userInfo user.User
	if info.User.Name != "" {
		userErr := global.GVA_DB.Model(&user.User{}).Where("name LIKE ?", "%"+info.User.Name+"%").First(&userInfo).Error
		if errors.Is(userErr, gorm.ErrRecordNotFound) {
			db = db.Where("u_id = 0")
		} else {
			db = db.Where("u_id = ?", userInfo.ID)
		}
	}
	err = db.Count(&total).Error
	err = db.Order("create_at desc").Limit(limit).Offset(offset).Preload("User").Preload("Topic").Find(&circles).Error
	for _, circle := range circles {
		var praiseNum string
		var commentNum string
		var circleViews string
		if circle.PraiseNum > 0 {
			praiseNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
		} else {
			praiseNum = "1w+"
		}
		if circle.CommentNum > 0 {
			commentNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
		} else {
			commentNum = "1w+"
		}
		if circle.Views > 0 {
			circleViews = strconv.Itoa(int(circle.Views)) + "w+"
		} else {
			circleViews = "1w+"
		}
		circleResponse := healthRes.NewCircleResponse{
			Cid:        circle.Cid,
			Name:       circle.User.Name,
			Avatar:     circle.User.Avatar,
			TopicName:  circle.Topic.Name,
			Text:       circle.Text,
			Img:        circle.Img,
			CreatedAt:  circle.CreatedAt,
			Views:      circleViews,
			PraiseNum:  praiseNum,
			CommentNum: commentNum,
			IsPraise:   circle.IsPraise,
		}
		result = append(result, circleResponse)
	}
	return result, total, err
}

// GetCircleInfoListByUid 通过用户ID获取健康圈列表
func (circleService *CircleService) GetCircleInfoListByUid(id uint) (list []healthRes.CircleResponse, err error) {
	var result []healthRes.CircleResponse
	var circles []health.Circle
	// 创建db
	db := global.GVA_DB.Model(&circles)
	if errors.Is(db.Where("status = 2 AND u_id = ?", id).Preload("User").Preload("Topic").Find(&circles).Error, gorm.ErrRecordNotFound) { // 判断是否存在数据
		return list, err
	}
	for _, circle := range circles {
		circleResponse := healthRes.CircleResponse{
			Cid:        circle.Cid,
			Name:       circle.User.Name,
			Avatar:     circle.User.Avatar,
			TopicName:  circle.Topic.Name,
			Text:       circle.Text,
			Img:        circle.Img,
			CreatedAt:  circle.CreatedAt,
			Views:      circle.Views,
			PraiseNum:  circle.PraiseNum,
			CommentNum: circle.CommentNum,
			IsPraise:   circle.IsPraise,
		}
		result = append(result, circleResponse)
	}
	return result, err
}

// GetOneDataByWhere 根据where条件获取一条数据
func (circleService *CircleService) GetOneDataByWhere(where map[string]interface{}, fields string) (info interface{}, err error) {
	var result health.Circle
	err = global.GVA_DB.Model(&result).Select(fields).Where(where).Limit(1).First(&result).Error
	return result, err
}

// FindCircleInfo 查询单条健康圈详情
func (circleService *CircleService) FindCircleInfo(cid uint, userID uint) (circleResponse healthRes.NewCircleResponse, err error) {
	var like health.CircleLike
	var circle health.Circle
	db := global.GVA_DB.Preload("User").Preload("Topic").Where("c_id = ?", cid).First(&circle)
	liErr := global.GVA_DB.Where("c_id = ? and user_id = ? and topic_type = ?", cid, userID, circle.Topic.ID).First(&like)
	err = db.Error
	if liErr.Error != nil {
		circle.IsPraise = false
	} else {
		circle.IsPraise = true
	}
	circle.Views += 1
	db.Update("views", circle.Views)
	var praiseNum string
	var commentNum string
	if circle.PraiseNum > 0 {
		praiseNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
	} else {
		praiseNum = "1w+"
	}
	if circle.CommentNum > 0 {
		commentNum = strconv.Itoa(int(circle.PraiseNum)) + "w+"
	} else {
		commentNum = "1w+"
	}
	circleResponse = healthRes.NewCircleResponse{
		Cid:        circle.Cid,
		Name:       circle.User.Name,
		Avatar:     circle.User.Avatar,
		TopicName:  circle.Topic.Name,
		Text:       circle.Text,
		Img:        circle.Img,
		CreatedAt:  circle.CreatedAt,
		Views:      strconv.Itoa(int(circle.Views)) + "w+",
		PraiseNum:  praiseNum,
		CommentNum: commentNum,
		IsPraise:   circle.IsPraise,
	}
	return circleResponse, err
}

// GetCircleCommentsInfoList 获取健康圈评论列表
// Author: [g-qs](https://github.com/g-qs)
func (circleService *CircleService) GetCircleCommentsInfoList(reqComments healthReq.ReqComments) (list []healthRes.CircleCommentsResponse, err error) {
	// 查询评论列表
	var comment []health.CircleComment
	err = global.GVA_DB.Model(&health.CircleComment{}).
		Preload("User").Preload("ToUser").
		Where("c_id = ?", reqComments.Cid).
		Order("create_at DESC").
		Find(&comment).Error
	if err != nil {
		return
	}
	for _, comments := range comment {
		list = append(list, healthRes.CircleCommentsResponse{
			ID:        comments.ID,
			Cid:       comments.Cid,
			ReplyID:   comments.ReplyID,
			CreatedAt: comments.CreatedAt,
			Uid:       comments.Uid,
			UidName:   comments.User.Name,
			Avatar:    comments.User.Avatar,
			Text:      comments.Text,
			ToUid:     comments.ToUid,
			ToUidName: comments.ToUser.Name,
		})
	}
	// 增加浏览量
	if uPErr := global.GVA_DB.Model(&health.Circle{}).Where("c_id = ?", reqComments.Cid).UpdateColumn("views", gorm.Expr("views + ?", 1)).Error; uPErr != nil {
		return nil, uPErr
	}
	return
}

// GetCircleCommentsList 获取评论列表【管理端】
// Author: [g-qs](https://github.com/g-qs)
func (circleService *CircleService) GetCircleCommentsList(info healthReq.CommentsSearch) (list []healthRes.CircleCommentsResponse, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&health.CircleComment{}).Where("c_id = ?", info.Cid)
	var comment []health.CircleComment
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("create_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}
	if info.Text != "" {
		db = db.Where("text LIKE ?", "%"+info.Text+"%")
	}
	var userInfo user.User
	if info.User.Name != "" {
		userErr := global.GVA_DB.Model(&user.User{}).Where("name LIKE ?", "%"+info.User.Name+"%").First(&userInfo).Error
		if errors.Is(userErr, gorm.ErrRecordNotFound) {
			db = db.Where("u_id = 0")
		} else {
			db = db.Where("u_id = ?", userInfo.ID)
		}
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}
	// 查询评论列表
	err = db.Preload("User").Preload("ToUser").Order("create_at DESC").Find(&comment).Error
	if err != nil {
		return
	}
	for _, comments := range comment {
		list = append(list, healthRes.CircleCommentsResponse{
			ID:        comments.ID,
			Cid:       comments.Cid,
			ReplyID:   comments.ReplyID,
			CreatedAt: comments.CreatedAt,
			Uid:       comments.Uid,
			UidName:   comments.User.Name,
			Avatar:    comments.User.Avatar,
			Text:      comments.Text,
			ToUid:     comments.ToUid,
			ToUidName: comments.ToUser.Name,
		})
	}
	// 增加浏览量
	if uPErr := global.GVA_DB.Model(&health.Circle{}).Where("c_id = ?", info.Cid).UpdateColumn("views", gorm.Expr("views + ?", 1)).Error; uPErr != nil {
		return nil, total, uPErr
	}
	return
}

// CreateCircleReportRecord 创建健康圈举报记录
// Author: [g-qs](https://github.com/g-qs)
func (circleService *CircleService) CreateCircleReportRecord(report *health.CircleReportRecord) (err error) {
	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 创建健康圈举报记录
		if err := global.GVA_DB.Create(&report).Error; err != nil {
			return err
		}
		// 修改健康圈状态
		if err = global.GVA_DB.Model(&health.Circle{}).Where("c_id = ?", report.ID).Update("status", 1).Error; err != nil {
			return err
		}
		return nil
	})
}

// CircleLike 点赞
func (circleService *CircleService) CircleLike(userID uint, cid uint) (circleResponse healthRes.CircleResponse, err error) {
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var circle health.Circle
		var circleLike health.CircleLike
		cdb := tx.Preload("User").Preload("Topic").Where("c_id = ?", cid).First(&circle)

		cldb := tx.Where("user_id = ? and c_id = ? and topic_type = ?", userID, cid, circle.Topic.ID).First(&circleLike)

		if errors.Is(cldb.Error, gorm.ErrRecordNotFound) {
			circle.PraiseNum += 1
			cldb = tx.Create(&health.CircleLike{
				UserID:    userID,
				CID:       cid,
				TopicType: circle.Topic.ID,
			})
			circle.IsPraise = true
			var uerr error
			var tb []byte
			var msg public2.Message
			var merr error

			var u user.User
			uerr = global.GVA_DB.First(&u, userID).Error
			if uerr != nil {
				goto onlyComment
			}
			tb, err = json.Marshal(map[string]interface{}{
				"root_id":   cid,
				"root_type": "circle",
				"user_name": u.Name,
				"avatar":    u.Avatar,
				"info":      u.Name + "给您点赞了",
			})

			msg = public2.Message{
				To:   circle.User.Phone,
				Info: tb,
				Type: "like",
			}
			merr = messageService.CreateMessage(&msg)
			if merr != nil {
				goto onlyComment
			}
		onlyComment:
		} else {
			circle.PraiseNum -= 1
			cldb = tx.Delete(&health.CircleLike{}, "user_id = ? and c_id = ? and topic_type = ?", userID, cid, circle.Topic.ID)
			circle.IsPraise = false
		}
		circleResponse = healthRes.CircleResponse{
			Cid:        circle.Cid,
			Name:       circle.User.Name,
			Avatar:     circle.User.Avatar,
			TopicName:  circle.Topic.Name,
			Text:       circle.Text,
			Img:        circle.Img,
			CreatedAt:  circle.CreatedAt,
			Views:      circle.Views,
			PraiseNum:  circle.PraiseNum,
			CommentNum: circle.CommentNum,
			IsPraise:   circle.IsPraise,
		}
		return cdb.Update("praise_num", circle.PraiseNum).Error
	})
	return
}

// DeleteCircle 删除健康圈
// Author [g-qs](https://gitee.com/g-qs)
func (circleService *CircleService) DeleteCircle(circle health.Circle) (err error) {
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		var circleComment health.CircleComment           // 健康圈下评论
		var circleLike health.CircleLike                 // 用户点赞健康圈
		var circleReportRecord health.CircleReportRecord // 健康圈举报记录
		var topicInfo topic.Topic                        // 话题
		// 获取话题
		circleInfo := tx.Where("c_id = ?", circle.Cid).First(&circle)
		tI := tx.Where("id = ?", circle.Tid).First(&topicInfo)
		// 删除健康圈下评论
		if dCcErr := tx.Where("c_id = ?", circle.Cid).Delete(&circleComment).Error; dCcErr != nil {
			return dCcErr
		}
		// 删除健康圈相关用户点赞
		if dClErr := tx.Where("c_id = ?", circle.Cid).Delete(&circleLike).Error; dClErr != nil {
			return dClErr
		}
		// 删除健康圈相关举报记录
		if dCrrErr := tx.Where("id = ?", circle.Cid).Delete(&circleReportRecord).Error; dCrrErr != nil {
			return dCrrErr
		}
		// 修改话题参与数
		*topicInfo.Number -= 1
		if tIErr := tI.Update("number", *topicInfo.Number).Error; tIErr != nil {
			return tIErr
		}
		// 删除健康圈
		return circleInfo.Delete(&circle).Error
	})
	return
}

// DeleteComment 删除评论
// Author [g-qs](https://gitee.com/g-qs)
func (circleService *CircleService) DeleteComment(comment health.CircleComment) (err error) {
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		// 获取健康圈
		if cCErr := tx.Where("id = ?", comment.ID).First(&comment).Error; cCErr != nil {
			return cCErr
		}
		// 修改健康圈评论数
		if cIErr := tx.Debug().Model(&health.Circle{}).Where("c_id = ?", comment.Cid).UpdateColumn("comment_num", gorm.Expr("comment_num - ?", 1)).Error; cIErr != nil {
			return cIErr
		}
		// 删除健康圈下评论
		return tx.Delete(&comment).Error
	})
	return
}
